#pragma once
#include "Config.h"
#include <atomic>
#include <mutex>
#include <thread>

namespace jetcar {

class MotorController {
public:
    // 1. 在类内提前定义枚举（public 允许外部访问，private 仅类内使用）
    enum Direction {
        STOP = 0,        // 停止（对应方向码 0）
        FORWARD = 1,     // 前进（对应方向码 1）
        BACKWARD = 2,    // 后退（对应方向码 2）
        LEFT_FRONT = 3,  // 左前（对应方向码 3）
        RIGHT_FRONT = 4, // 右前（对应方向码 4）
        LEFT_BACK = 5,   // 左后（对应方向码 5）
        RIGHT_BACK = 6   // 右后（对应方向码 6）
    };
    
    MotorController(const Config &cfg);
    ~MotorController();

    // high-level commands (thread-safe)
    void setTarget(int direction, int speed); // direction: 0 stop, 1 forward, 2 back, 3 left, 4 right
    void stop(); // immediate target stop (but actual decel happens smoothly)

    // start/stop worker threads
    bool start();
    void stopAll();
    bool selfCheck(int motor_id);

private:
    Config cfg_;
    std::atomic<int> target_direction_; // desired direction
    std::atomic<int> target_speed_;     // desired speed (rpm)
    std::atomic<int> current_speed_left_;
    std::atomic<int> current_speed_right_;
    std::mutex mtx_;
    std::atomic<bool> running_;

    // threads
    std::thread control_thread_;
    std::thread heartbeat_thread_left_;
    std::thread heartbeat_thread_right_;

    void controlLoop();
    void heartbeatLoop(int canId);
    void sendMotorCommands(int left_rpm, int right_rpm);
    void encodeAndSend(int motor_id, int rpm); // wrapper to send CAN frames (payload format)
};



} // namespace jetcar

using DirectionCode = jetcar::MotorController::Direction;
